﻿# include<iostream>
using namespace std;
# include<vector>
# include <map>
# include <string>

//int main()
//{
//	/*struct Date
//	{
//		int year;
//		int month;
//		int day;
//	};
//	int arr[10] = { 5,1,2,3 };*/
//	/*Date d1={ 2025,10,7 };*/
//	
//
//    //  内置类型⽀持
//	int a{ 1 };
//	double b{ 2.2 };
//	char c{ 'a' };
//  
//    class Date
//    {
//    public:
//        Date(int year = 1, int month = 1, int day = 1)
//            :_year(year)
//            , _month(month)
//            , _day(day)
//        {
//            cout << "调用构造函数" << endl;
//        }
//        Date(const Date& d)
//            :_year(d._year)
//            , _month(d._month)
//            , _day(d._day)
//        {
//            cout << "调用拷贝构造函数" << endl;
//        }
//    private:
//        int _year;
//        int _month;
//        int _day;
//    };
//       /* Date d1 = { 2025, 1, 1 };
//        cout << endl;
//        const Date& d2 = { 2024, 7, 25 };*/
//
//       
//
//        //Date d3 = { 2025 };      //c++98支持的单参数隐式类型转换可以去掉{}
//        //Date d4 = 2025;     
//        //Date d33{ 2025 }; //有{}可以省略=
//        //Date d4  2025;     //没有{}不能省略=
//
//
//        Date d1{ 2025, 1, 1 };         //c++11支持的{} 可以省略=
//        //cout << endl;
//        //const Date& d2{ 2024, 7, 25 };
//        //Date d5 = 2025, 1, 1;    //c++11支持的{}  不可以省略{}
//
//
//        vector<Date> v;
//        v.push_back(d1); //直接插入对象的方式
//        v.push_back(Date(2025, 1, 1)); //匿名对象的方式
//        v.push_back({ 2025, 1, 1 });  //{}的方式  相较于前两种 这种方法非常简便
//
//        map<string, string>m1;
//        m1.insert({ "sss","ttt" });
//
//       /* vector<int>vv({ 1,2,3,4,5,6 }); 
//        vector<string>ss({ "hh""ttt""eee" });*/
//
//       /* vector<int>vv({ 1,2,3,4,5,6 });*/
//
//        /*int arr[]= { 1,2,3,4,5,6 };
//        for (int x : arr)
//            vv.push_back(x);*/
//
//        vector<int>vv({ 1,2,3,4,5,6 });   //直接将{}里面内容转换为initia_list 然后进行构造
//
//        vector<int>vv{ 1,2,3,4,5,6 };  //先用{}调用构造 构造了一个临时对象 然后进行拷贝构造  不过编译器最终会优化为直接构造 和上面的一样了就
//
//        map<string, string>m1{{"sss","ttt"},{"sss","ttt"}};
//
//
//
//        return 0;
//}

int main()
{
	
	//左值  可以取地址
    int* p = new int(0);
	int b = 1;
	const int c = b;
	*p = 10;
	string s("111111");
	s[0] = 'x';       //函数调用 但是返回的是引用 是左值
	cout << &c << endl;
	cout << (void*)&s[0] << endl;

	// 右值：不能取地址
	double x = 1.1, y = 2.2;

	10;              //常量
	x + y;             //表达式
	fmin(x, y);    //函数调用 是传值返回 是右值
	string("11111"); //匿名对象

	/*cout << &10 << endl;
    cout << &(x+y) << endl;
    cout << &(fmin(x, y)) << endl;
    cout << &string("11111") << endl;*/

	// 左值引⽤给左值取别名
	int& r1 = b;
	int*& r2 = p;
	int& r3 = *p;
	string& r4 = s;
	char& r5 = s[0];
	// 右值引⽤给右值取别名
	int&& rr1 = 10;
	double&& rr2 = x + y;
	double&& rr3 = fmin(x, y);
	string&& rr4 = string("11111");

	// 左值引⽤不能直接引⽤右值，但是const左值引⽤可以引⽤右值
	const int& rx1 = 10;
	const double& rx2 = x + y;
	const double& rx3 = fmin(x, y);
	const string& rx4 = string("11111");

	// 右值引⽤不能直接引⽤左值，但是右值引⽤可以引⽤move(左值)
	int&& rrx1 = move(b);
	int*&& rrx2 = move(p);
	int&& rrx3 = move(*p);
	string&& rrx4 = move(s);

	int&& rrx1 = (int&&)b;
	int*&& rrx2 = (int*&&)p;
	int&& rrx3 = (int&&)*p;
	string&& rrx5 = (string&&)s;

	// 这⾥要注意的是，rr1的属性是左值，所以不能再被右值引⽤绑定，除⾮move⼀下

	int&& rr1 = move(b);
	int& r6 = rr1;
	int&& rrx6 = rr1;
	int&& rrx6 = move(rr1);
}
